home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / CONTRIB / MAN_PC.ZIP / man_pc / whatis / mkwhatis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-20  |  6.9 KB  |  372 lines

  1. /*
  2.  *    mkwhatis - read/print "SEE ALSO" or NAME section of unformatted manpage
  3.  *
  4.  *    finds .SH "SEE ALSO" or .SH NAME line and prints next line(s) until
  5.  *    either EOF or first char of line is '.'
  6.  *
  7.  *    this is a tool to help build the whatis(1) databases. the idea is
  8.  *    to feed it a list of manpages (source form). it does a reasonable
  9.  *    job, but is not perfect. you may have to do some editing...
  10.  *
  11.  *    the format for each line of the whatis databases is:
  12.  *
  13.  *    name%aliases%section%subsection%description%xrefs%keywords
  14.  *
  15.  *    name        program/routine/etc name. (required)
  16.  *    alias        if this sources another manpage or refered by another
  17.  *            name. a comma-separated list. (optional)
  18.  *    section        number [0-9nlo] (required)
  19.  *    subsection    single capital letter (optional)
  20.  *    description    what this is, ascii string (required)
  21.  *    xref        basically "SEE ALSO". a comma-separated list (optional)
  22.  *    keywords    any descriptive keywords. comma-sep list (optional)
  23.  *
  24.  *    optional fields contain only a '_' char.
  25.  *
  26.  *    here is an example:
  27.  *
  28.  *    unixmode%_%5%_%Extended Filename Standard%tcsh(1),sh(1)%TOS,MiNT,file,glob,links,shell,standard
  29.  *
  30.  *    it assumes manpage (src) that look like this:
  31.  *
  32.  *        .TH FOO 1X            <-- gives section, subsection
  33.  *        .SH NAME
  34.  *        foo \- blah blah blah        <-- gives name, desc
  35.  *        .SH DESCIPTION
  36.  *        .
  37.  *        .
  38.  *        .
  39.  *        .SH "SEE ALSO"
  40.  *        bar(1), foobar(5)        <-- gives xref
  41.  *        .SH SOMETHING  (or eof)
  42.  *
  43.  *    or
  44.  *        .TH FOO 1 LOCAL            <-- gives section, subsection
  45.  *        .
  46.  *        .
  47.  *        .
  48.  *
  49.  *    it does NOT handle sourced files (aliases), ie:
  50.  *
  51.  *        .so man1/foo.1
  52.  *
  53.  *    at a minimum, you will have to add keywords yourself.
  54.  */
  55.  
  56. static char *rcsid_mkwhatis_c = "$Id: mkwhatis.c,v 2.0 1992/09/13 05:02:44 rosenkra Exp $";
  57. static char *version = "mkwhatis 2.0 92/09/13 rosenkra@convex.com";
  58. static char *myname = "mkwhatis";
  59.  
  60.  
  61. /*
  62.  * $Log: mkwhatis.c,v $
  63.  * Revision 2.0  1992/09/13  05:02:44  rosenkra
  64.  * total rewrite. this if first rev of this file.
  65.  *
  66.  *
  67.  */
  68.  
  69. #include <stdio.h>
  70. #include <string.h>
  71. #include <stdlib.h>
  72.  
  73. #define EOS        '\0'
  74. #define NL        '\n'
  75. #define CR        '\r'
  76. #define TAB        '\t'
  77. #define SPC        ' '
  78. #define DOT        '.'
  79. #define DASH        '-'
  80.  
  81.  
  82. #define NAME        "NAME"
  83. #define SEE_ALSO    "SEE ALSO"
  84. #define SEE_ALSO_Q    "\"SEE ALSO"
  85.  
  86.  
  87. #define PR_NULL_FIELD    printf("%%_");
  88.  
  89.  
  90. #define B_SIZE        1024
  91.  
  92.  
  93. char    buf[B_SIZE];
  94. FILE   *stream;
  95.  
  96.  
  97. void    read_xref (void);
  98. char   *skipwhite (char *);
  99. char   *skipword (char *);
  100. char   *finddash (char *);
  101. void    kill_newline (char *);
  102.  
  103.  
  104. void main (int argc, char *argv[])
  105. {
  106.     char   *ps;
  107.     int    sec;
  108.     int    subsec;
  109.     int    got_xref = 0;
  110.     int    got_name = 0;
  111.  
  112.  
  113.  
  114.     for (argc--, argv++; argc && **argv == '-'; argc--, argv++)
  115.     {
  116.         switch (*(*argv+1))
  117.         {
  118.         default:
  119.             fprintf (stderr,"%s\n", version);
  120.             fprintf (stderr,
  121.                 "usage: %s [-A | -N | -S | -B] file...\n",
  122.                 myname);
  123.             exit (1);
  124.         }
  125.     }
  126.  
  127.  
  128.     /*
  129.      *   args are manpage source files
  130.      */
  131.     for ( ; argc && *argv; argc--, argv++)
  132.     {
  133.         if ((stream = fopen (*argv, "r")) == (FILE *) NULL)
  134.         {
  135.             fprintf (stderr,
  136.                 "%s: could not open %s\n", myname, *argv);
  137.             continue;
  138.         }
  139.  
  140.  
  141.         got_xref = 0;
  142.         got_name = 0;
  143.  
  144.         while (1)
  145.         {
  146.             fgets (buf, B_SIZE-1, stream);
  147.             if (feof (stream))
  148.             {
  149.                 /* if we exit loop here, things were probably
  150.                    ok, but there was no SEE ALSO. put out
  151.                    an appropriate ending... */
  152.  
  153.                 if (got_name && !got_xref)
  154.                     printf ("%%_%%_\n");
  155.                 else
  156.                     printf ("\n");
  157.  
  158.                 goto next1;            /* ERROR? */
  159.             }
  160.             kill_newline (buf);
  161.  
  162.  
  163.             /*
  164.              *   look for .TH or .SH
  165.              */
  166.             if (buf[0] != DOT)
  167.                 continue;
  168.             if (buf[1] == 'T' && buf[2] == 'H')
  169.             {
  170.                 ps = buf;
  171.  
  172.                 /* skip .TH */
  173.                 if ((ps = skipword (ps)) && *ps == EOS)
  174.                     goto next1;        /* ERROR */
  175.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  176.                     goto next1;        /* ERROR */
  177.  
  178.                 /* skip FOO */
  179.                 if ((ps = skipword (ps)) && *ps == EOS)
  180.                     goto next1;        /* ERROR */
  181.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  182.                     goto next1;        /* ERROR */
  183.  
  184.                 if (*ps)
  185.                     sec = *ps;
  186.                 else
  187.                     sec = '1';    /* assume */
  188.                 
  189.                 subsec = EOS;        /* none */
  190.  
  191.                 /* skip sect */
  192.                 if ((ps = skipword (ps)) && *ps == EOS)
  193.                     continue;
  194.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  195.                     continue;
  196.  
  197.                 if (*ps)
  198.                     subsec = *ps;
  199.                 
  200.             }
  201.             else if (buf[1] == 'S' && buf[2] == 'H')
  202.             {
  203.                 ps = buf;
  204.  
  205.                 /* skip .SH */
  206.                 if ((ps = skipword (ps)) && *ps == EOS)
  207.                     goto next1;        /* ERROR */
  208.                 if ((ps = skipwhite (ps)) && *ps == EOS)
  209.                     goto next1;        /* ERROR */
  210.  
  211.                 if (!strncmp (ps, NAME, 4))
  212.                 {
  213.                     char *dsh;
  214.  
  215.                     fgets (buf, B_SIZE-1, stream);
  216.                     if (feof (stream))
  217.                     {
  218.                         goto next1;    /* ERROR */
  219.                     }
  220.                     kill_newline (buf);
  221.  
  222.                     ps = buf;
  223.                     
  224.                     if ((ps = finddash (ps)) && *ps == EOS)
  225.                         goto next1;    /* ERROR */
  226.                     
  227.                     /* skip past dash to desc */
  228.                     dsh = ps;
  229.                     if ((ps = skipword (ps)) && *ps == EOS)
  230.                         goto next1;    /* ERROR */
  231.                     if ((ps = skipwhite (ps)) && *ps == EOS)
  232.                         goto next1;    /* ERROR */
  233.  
  234.                     /* find end of name, going backwards
  235.                        from dash */
  236.                     if (dsh[-1] == '\\')
  237.                         dsh--;
  238.  
  239.                     while (dsh > buf
  240.                     && (dsh[-1] == SPC || dsh[-1] == TAB))
  241.                         dsh--;
  242.                     *dsh = EOS;
  243.  
  244.                     /* check for name */
  245.                     if (buf[0] == EOS)
  246.                         goto next1;    /* ERROR */
  247.  
  248.                     printf ("%s", buf);    /* name */
  249.  
  250.                     PR_NULL_FIELD;        /* alias */
  251.  
  252.                     printf ("%%%c", sec);    /* section */
  253.  
  254.                     if (subsec)        /* subsect */
  255.                         printf ("%%%c", subsec);
  256.                     else
  257.                         PR_NULL_FIELD;
  258.  
  259.                     if (ps && *ps)        /* desc */
  260.                         printf ("%%%s", ps);
  261.                     else
  262.                         PR_NULL_FIELD;
  263.  
  264.                     got_name = 1;
  265.                 }
  266.                 else if (strncmp (ps, SEE_ALSO, 8) == 0
  267.                 ||       strncmp (ps, SEE_ALSO_Q, 9) == 0)
  268.                 {
  269.                     got_xref = 1;
  270.                     printf ("%%");        /* xref */
  271.  
  272.                     read_xref ();
  273.  
  274.                     break;        /* normal exit! */
  275.                 }
  276.             }
  277.         }
  278.         if (!got_xref)
  279.             PR_NULL_FIELD;                /* xref */
  280.  
  281.         PR_NULL_FIELD;                    /* keywords */
  282.         printf ("\n");
  283. next1: ;
  284.         fclose(stream);
  285.     }
  286.     exit(0);
  287. }
  288.  
  289.  
  290.  
  291. /*------------------------------*/
  292. /*    read_xref        */
  293. /*------------------------------*/
  294. void read_xref (void)
  295. {
  296.     char   *ps;
  297.  
  298.     while (1)
  299.     {
  300.         fgets (buf, B_SIZE-1, stream);
  301.         if (feof (stream) || buf[0] == '.')
  302.             return;
  303.         kill_newline (buf);
  304.  
  305. /*        fputs (buf, stdout);*/
  306.         for (ps = buf; *ps; ps++)
  307.         {
  308.             if (*ps == SPC)
  309.                 continue;
  310.             putchar (*ps);
  311.         }
  312.     }
  313.     return;
  314. }
  315.  
  316.  
  317.  
  318. /*------------------------------*/
  319. /*    skipwhite        */
  320. /*------------------------------*/
  321. char *skipwhite (char *ps)
  322. {
  323.     while (*ps && (*ps == SPC || *ps == TAB))
  324.         ps++;
  325.     return (ps);
  326. }
  327.  
  328.  
  329.  
  330. /*------------------------------*/
  331. /*    skipword        */
  332. /*------------------------------*/
  333. char *skipword (char *ps)
  334. {
  335.     while (*ps && (*ps != SPC && *ps != TAB))
  336.         ps++;
  337.     return (ps);
  338. }
  339.  
  340.  
  341.  
  342. /*------------------------------*/
  343. /*    finddash        */
  344. /*------------------------------*/
  345. char *finddash (char *ps)
  346. {
  347.     while (*ps && *ps != DASH)
  348.         ps++;
  349.     return (ps);
  350. }
  351.  
  352.  
  353.  
  354. /*------------------------------*/
  355. /*    kill_newline        */
  356. /*------------------------------*/
  357. void kill_newline (char *ps)
  358. {
  359.     while (*ps)
  360.     {
  361.         if (*ps == NL || *ps == CR)
  362.         {
  363.             *ps = EOS;
  364.             return;
  365.         }
  366.         ps++;
  367.     }
  368.     return;
  369. }
  370.  
  371.  
  372.